home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / futilsrc.zoo / fileutil / lib / fsinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-03  |  11.1 KB  |  473 lines

  1. /* fsinfo.c -- return info about mounted filesystems
  2.    Copyright (C) 1991 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <errno.h>
  21. #include "fsinfo.h"
  22.  
  23. #ifdef STDC_HEADERS
  24. #include <stdlib.h>
  25. #else
  26. extern int errno;
  27. void exit ();
  28. void free ();
  29. #endif
  30. #if defined(USG) || defined(STDC_HEADERS)
  31. #include <string.h>
  32. #else
  33. #include <strings.h>
  34. #endif
  35.  
  36. int statfs ();
  37.  
  38. int xatoi ();
  39. char *strstr ();
  40. char *xmalloc ();
  41. char *xrealloc ();
  42. char *xstrdup ();
  43. void error ();
  44.  
  45. #ifdef FS_MNTENT
  46. #include <sys/vfs.h>
  47. #include <mntent.h>
  48. #if !defined(MOUNTED) && defined(MNT_MNTTAB) /* HP-UX. */
  49. #define MOUNTED MNT_MNTTAB
  50. #endif
  51. #endif /* FS_MNTENT */
  52.  
  53. #ifdef FS_GETMNT
  54. #include <sys/param.h>
  55. #include <sys/mount.h>
  56. #include <sys/fs_types.h>
  57. int getmnt ();
  58. #endif
  59.  
  60. #ifdef FS_USG_STATFS
  61. #include <mnttab.h>
  62. #include <sys/statfs.h>
  63. #include <sys/fstyp.h>
  64. #endif
  65.  
  66. #ifdef FS_STATVFS
  67. #include <sys/statvfs.h>
  68. #include <sys/mnttab.h>
  69. #endif
  70.  
  71. #ifdef FS_STATFS
  72. #include <sys/mount.h>
  73.  
  74. char *
  75. fstype_to_string (t)
  76.      short t;
  77. {
  78.   switch (t)
  79.     {
  80.     case MOUNT_UFS:
  81.       return "ufs";
  82.     case MOUNT_NFS:
  83.       return "nfs";
  84.     case MOUNT_PC:
  85.       return "pc";
  86. #ifdef MOUNT_MFS
  87.     case MOUNT_MFS:
  88.       return "mfs";
  89. #endif
  90. #ifdef MOUNT_LO
  91.     case MOUNT_LO:
  92.       return "lo";
  93. #endif
  94. #ifdef MOUNT_TFS
  95.     case MOUNT_TFS:
  96.       return "tfs";
  97. #endif
  98. #ifdef MOUNT_TMP
  99.     case MOUNT_TMP:
  100.       return "tmp";
  101. #endif
  102.     default:
  103.       return "?";
  104.     }
  105. }
  106. #endif
  107.  
  108. #ifdef __MINT__
  109. #include <dirent.h>
  110. #include <stat.h>
  111. #include <osbind.h>
  112.  
  113. /* keep the linker happy */
  114. void sync() { return; };
  115. #endif
  116.  
  117. /* Return a list of the currently mounted filesystems, or NULL on error.
  118.    Add each entry to the tail of the list so that they stay in order.
  119.    If NEED_FS_TYPE is nonzero, make sure the filesystem type fields in
  120.    the returned list are valid. */
  121.  
  122. struct mount_entry *
  123. read_filesystem_list (need_fs_type)
  124.      int need_fs_type;
  125. {
  126.   struct mount_entry *mount_list;
  127.   struct mount_entry *me;
  128.   struct mount_entry *mtail;
  129.  
  130.   /* Start the list off with a dummy entry. */
  131.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  132.   me->me_next = NULL;
  133.   mount_list = mtail = me;
  134.  
  135. #ifdef FS_MNTENT        /* 4.3BSD, SunOS, HP-UX */
  136.   {
  137.     struct mntent *mnt;
  138.     char *table = MOUNTED;    /* /etc/mtab, usually. */
  139.     FILE *fp;
  140.     char *devopt;
  141.  
  142.     fp = setmntent (table, "r");
  143.     if (fp == NULL)
  144.       return NULL;
  145.  
  146.     while ((mnt = getmntent (fp)))
  147.       {
  148.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  149.     me->me_devname = xstrdup (mnt->mnt_fsname);
  150.     me->me_mountdir = xstrdup (mnt->mnt_dir);
  151.     me->me_type = xstrdup (mnt->mnt_type);
  152.     devopt = strstr (mnt->mnt_opts, "dev=");
  153.     if (devopt)
  154.       {
  155.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  156.           me->me_dev = xatoi (devopt + 6);
  157.         else
  158.           me->me_dev = xatoi (devopt + 4);
  159.       }
  160.     else
  161.       me->me_dev = -1;    /* Magic; means not known yet. */
  162.     me->me_next = NULL;
  163.  
  164.     /* Add to the linked list. */
  165.     mtail->me_next = me;
  166.     mtail = me;
  167.       }
  168.  
  169.     if (endmntent (fp) == 0)
  170.       return NULL;
  171.   }
  172. #endif /* FS_MNTENT */
  173.  
  174. #ifdef FS_GETMNT        /* Ultrix */
  175.   {
  176.     int offset = 0;
  177.     int val;
  178.     struct fs_data fsd;
  179.  
  180.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  181.               (char *) 0)) > 0)
  182.       {
  183.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  184.     me->me_devname = xstrdup (fsd.fd_req.devname);
  185.     me->me_mountdir = xstrdup (fsd.fd_req.path);
  186.     me->me_type = gt_names[fsd.fd_req.fstype];
  187.     me->me_dev = fsd.fd_req.dev;
  188.     me->me_next = NULL;
  189.  
  190.     /* Add to the linked list. */
  191.     mtail->me_next = me;
  192.     mtail = me;
  193.       }
  194.     if (val < 0)
  195.       return NULL;
  196.   }
  197. #endif /* FS_GETMNT */
  198.  
  199. #ifdef FS_USG_STATFS        /* SVR3.2 */
  200.   {
  201.     struct mnttab mnt;
  202.     char *table = "/etc/mnttab";
  203.     FILE *fp;
  204.  
  205.     fp = fopen (table, "r");
  206.     if (fp == NULL)
  207.       return NULL;
  208.  
  209.     while (fread (&mnt, sizeof mnt, 1, fp) > 0)
  210.       {
  211.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  212.     me->me_devname = xstrdup (mnt.mt_dev);
  213.     me->me_mountdir = xstrdup (mnt.mt_filsys);
  214.     me->me_dev = -1;    /* Magic; means not known yet. */
  215.     me->me_type = "";
  216.     if (need_fs_type)
  217.       {
  218.         struct statfs fsd;
  219.         char typebuf[FSTYPSZ];
  220.  
  221.         if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  222.         && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  223.           me->me_type = xstrdup (typebuf);
  224.       }
  225.     me->me_next = NULL;
  226.  
  227.     /* Add to the linked list. */
  228.     mtail->me_next = me;
  229.     mtail = me;
  230.       }
  231.  
  232.     if (fclose (fp) == EOF)
  233.       return NULL;
  234.   }
  235. #endif /* FS_USG_STATFS */
  236.  
  237. #ifdef FS_STATVFS        /* SVR4 */
  238.   {
  239.     struct mnttab mnt;
  240.     char *table = MNTTAB;
  241.     FILE *fp;
  242.     int ret;
  243.  
  244.     fp = fopen (table, "r");
  245.     if (fp == NULL)
  246.       return NULL;
  247.  
  248.     while ((ret = getmntent (fp, &mnt)) == 0)
  249.       {
  250.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  251.     me->me_devname = xstrdup (mnt.mnt_special);
  252.     me->me_mountdir = xstrdup (mnt.mnt_mountp);
  253.     me->me_type = xstrdup (mnt.mnt_fstype);
  254.     me->me_dev = -1;    /* Magic; means not known yet. */
  255.     me->me_next = NULL;
  256.  
  257.     /* Add to the linked list. */
  258.     mtail->me_next = me;
  259.     mtail = me;
  260.       }
  261.  
  262.     if (ret > 0)
  263.       return NULL;
  264.    if (fclose (fp) == EOF)
  265.       return NULL;
  266.   }
  267. #endif
  268.  
  269. #ifdef FS_STATFS        /* 4.4BSD */
  270.   {
  271.     struct statfs *fsp;
  272.     int entries;
  273.  
  274.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  275.     if (entries < 0)
  276.       return NULL;
  277.     while (entries-- > 0)
  278.       {
  279.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  280.     me->me_devname = xstrdup (fsp->f_mntfromname);
  281.     me->me_mountdir = xstrdup (fsp->f_mntonname);
  282.     me->me_type = fstype_to_string (fsp->f_type);
  283.     me->me_dev = -1;    /* Magic; means not known yet. */
  284.     me->me_next = NULL;
  285.  
  286.     /* Add to the linked list. */
  287.     mtail->me_next = me;
  288.     mtail = me;
  289.     fsp++;
  290.       }
  291.   }
  292. #endif /* FS_STATFS */
  293.  
  294. #ifdef __MINT__            /* MiNT on Atari ST */
  295.   {
  296.     static char ubuf[128] = "u:/";
  297.     DIR *udrv;
  298.     struct dirent *next;
  299.     struct stat statbuf;
  300.     long drvmap, ssp;
  301.     int i;
  302.     int offset;
  303.     struct mount_entry *him;
  304.  
  305.     offset = (Dgetdrv() == 'U'-'A') ? 2 : 0;
  306.     ssp = Super(0L);
  307.     drvmap = *((long *)0x4c2);    /* get which drives are attached */
  308.     if ((*(short *)0x4a6) != 2)
  309.       drvmap &= ~2;        /* drive B: isn't really there */
  310.     Super(ssp);
  311.  
  312.     for (i = 0; i < 32; i++)
  313.       {
  314.         if (drvmap & (1L << i))
  315.           {
  316.             me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  317.             me->me_devname = xstrdup("a:");
  318.             me->me_devname[0] = 'a'+i;
  319.             me->me_mountdir = xstrdup(ubuf);
  320.             me->me_mountdir[0] = me->me_devname[0];
  321.             me->me_dev = i;
  322.             me->me_next = NULL;
  323.             me->me_type = xstrdup( (i < 16) ? "tos" : "pseudo" );
  324.             mtail->me_next = me;
  325.             mtail = me;
  326.           }
  327.       }
  328.     udrv = opendir(ubuf);
  329.     if (udrv)
  330.       {
  331.         while (next = readdir(udrv))
  332.           {
  333.         strcpy(ubuf+3, next->d_name);
  334.         lstat(ubuf, &statbuf);
  335.         if ( (statbuf.st_mode & S_IFMT) == S_IFDIR )
  336.             for (him = mount_list->me_next; him; him = him->me_next)
  337.           {
  338.             if (him->me_devname[0] - 'a' == statbuf.st_dev)
  339.               {
  340.                 free(him->me_mountdir);
  341.             him->me_mountdir = xstrdup(ubuf+offset);
  342.             break;
  343.                       }
  344.           }
  345.       }
  346.       }
  347.   }
  348. #endif /* __MINT__ */
  349.  
  350.   /* Free the dummy head. */
  351.   me = mount_list;
  352.   mount_list = mount_list->me_next;
  353.   free (me);
  354.   return mount_list;
  355. }
  356.  
  357. /* Fill in the fields of FSP with information about space usage on
  358.    the filesystem on which PATH is a node.
  359.    Return 0 if successful, -1 if not. */
  360.  
  361. int
  362. get_fs_usage (path, fsp)
  363.      char *path;
  364.      struct fs_usage *fsp;
  365. {
  366. #ifdef FS_MNTENT
  367.   struct statfs fsd;
  368.  
  369.   if (statfs (path, &fsd) != 0)
  370.     return -1;
  371.   fsp->fsu_blocks = fsd.f_blocks;
  372.   fsp->fsu_bfree = fsd.f_bfree;
  373.   fsp->fsu_bavail = fsd.f_bavail;
  374.   fsp->fsu_files = fsd.f_files;
  375.   fsp->fsu_ffree = fsd.f_ffree;
  376. #endif /* FS_MNTENT */
  377.  
  378. #ifdef FS_USG_STATFS
  379. #define f_bavail f_bfree
  380.   struct statfs fsd;
  381.  
  382.   if (statfs (path, &fsd, sizeof fsd, 0) < 0)
  383.     return -1;
  384.   fsp->fsu_blocks = (fsd.f_blocks + 1) / 2;
  385.   fsp->fsu_bfree = (fsd.f_bfree + 1) / 2;
  386.   fsp->fsu_bavail = (fsd.f_bavail + 1) / 2;
  387.   fsp->fsu_files = fsd.f_files;
  388.   fsp->fsu_ffree = fsd.f_ffree;
  389. #endif
  390.  
  391. #ifdef FS_STATVFS
  392.   struct statvfs fsd;
  393.  
  394.   if (statvfs (path, &fsd) < 0)
  395.     return -1;
  396.   fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_frsize);
  397.   fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_frsize);
  398.   fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_frsize);
  399.   fsp->fsu_files = fsd.f_files;
  400.   fsp->fsu_ffree = fsd.f_ffree;
  401. #endif
  402.  
  403. #ifdef FS_STATFS
  404.   struct statfs fsd;
  405.  
  406.   if (statfs (path, &fsd) < 0)
  407.     return -1;
  408.   fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_fsize);
  409.   fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_fsize);
  410.   fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_fsize);
  411.   fsp->fsu_files = fsd.f_files;
  412.   fsp->fsu_ffree = fsd.f_ffree;
  413. #endif
  414.  
  415. #ifdef FS_GETMNT
  416.   struct fs_data fsd;
  417.  
  418.   if (statfs (path, &fsd) != 1)
  419.     return -1;
  420.   fsp->fsu_blocks = fsd.fd_req.btot;
  421.   fsp->fsu_bfree = fsd.fd_req.bfree;
  422.   fsp->fsu_bavail = fsd.fd_req.bfreen;
  423.   fsp->fsu_files = fsd.fd_req.gtot;
  424.   fsp->fsu_ffree = fsd.fd_req.gfree;
  425. #endif /* FS_GETMNT */
  426.  
  427. #ifdef __MINT__
  428.   extern int errno;
  429.   struct stat sbuf;
  430.   long dfree[4], r, clsiz;
  431.  
  432.   if (stat(path, &sbuf)) return -1;
  433.   r = Dfree(dfree, sbuf.st_dev+1);
  434.   if (r) {
  435.     errno = -r;
  436.     return -1;
  437.   }
  438.   clsiz = dfree[2] * dfree[3];
  439.   fsp->fsu_files = dfree[1];
  440.   fsp->fsu_ffree = dfree[0];
  441.   fsp->fsu_blocks = ((dfree[1] * clsiz) + 1) / 1024;
  442.   fsp->fsu_bfree = fsp->fsu_bavail = ((dfree[0] * clsiz) + 1) / 1024;
  443. #endif /* __MINT__ */
  444.  
  445.   return 0;
  446. }
  447.  
  448. /* Return the value of the hexadecimal number represented by CP.
  449.    No prefix (like '0x') or suffix (like 'h') is expected to be
  450.    part of CP. */
  451.  
  452. int
  453. xatoi (cp)
  454.      char *cp;
  455. {
  456.   int val;
  457.   
  458.   val = 0;
  459.   while (*cp)
  460.     {
  461.       if (*cp >= 'a' && *cp <= 'f')
  462.     val = val * 16 + *cp - 'a' + 10;
  463.       else if (*cp >= 'A' && *cp <= 'F')
  464.     val = val * 16 + *cp - 'A' + 10;
  465.       else if (*cp >= '0' && *cp <= '9')
  466.     val = val * 16 + *cp - '0';
  467.       else
  468.     break;
  469.       cp++;
  470.     }
  471.   return val;
  472. }
  473.